#ifndef THINK_THINK_MODEL_H
#define THINK_THINK_MODEL_H

static char* think_model =
	"\n"
	"// +----------------------------------------------------------------------\n"
	"// | ThinkPHP [ WE CAN DO IT JUST THINK ]\n"
	"// +----------------------------------------------------------------------\n"
	"// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.\n"
	"// +----------------------------------------------------------------------\n"
	"// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n"
	"// +----------------------------------------------------------------------\n"
	"// | Author: liu21st <liu21st@gmail.com>\n"
	"// +----------------------------------------------------------------------\n"
	"\n"
	"namespace think;\n"
	"\n"
	"use BadMethodCallException;\n"
	"use InvalidArgumentException;\n"
	"use think\\db\\Query;\n"
	"use think\\exception\\ValidateException;\n"
	"use think\\model\\Collection as ModelCollection;\n"
	"use think\\model\\Relation;\n"
	"use think\\model\\relation\\BelongsTo;\n"
	"use think\\model\\relation\\BelongsToMany;\n"
	"use think\\model\\relation\\HasMany;\n"
	"use think\\model\\relation\\HasManyThrough;\n"
	"use think\\model\\relation\\HasOne;\n"
	"use think\\model\\relation\\MorphMany;\n"
	"use think\\model\\relation\\MorphOne;\n"
	"use think\\model\\relation\\MorphTo;\n"
	"\n"
	"/**\n"
	" * Class Model\n"
	" * @package think\n"
	" * @mixin Query\n"
	" */\n"
	"abstract class Model implements \\JsonSerializable, \\ArrayAccess\n"
	"{\n"
	"    // 数据库查询对象池\n"
	"    protected static $links = [];\n"
	"    // 数据库配置\n"
	"    protected $connection = [];\n"
	"    // 父关联模型对象\n"
	"    protected $parent;\n"
	"    // 数据库查询对象\n"
	"    protected $query;\n"
	"    // 当前模型名称\n"
	"    protected $name;\n"
	"    // 数据表名称\n"
	"    protected $table;\n"
	"    // 当前类名称\n"
	"    protected $class;\n"
	"    // 回调事件\n"
	"    private static $event = [];\n"
	"    // 错误信息\n"
	"    protected $error;\n"
	"    // 字段验证规则\n"
	"    protected $validate;\n"
	"    // 数据表主键 复合主键使用数组定义 不设置则自动获取\n"
	"    protected $pk;\n"
	"    // 数据表字段信息 留空则自动获取\n"
	"    protected $field = [];\n"
	"    // 数据排除字段\n"
	"    protected $except = [];\n"
	"    // 数据废弃字段\n"
	"    protected $disuse = [];\n"
	"    // 只读字段\n"
	"    protected $readonly = [];\n"
	"    // 显示属性\n"
	"    protected $visible = [];\n"
	"    // 隐藏属性\n"
	"    protected $hidden = [];\n"
	"    // 追加属性\n"
	"    protected $append = [];\n"
	"    // 数据信息\n"
	"    protected $data = [];\n"
	"    // 原始数据\n"
	"    protected $origin = [];\n"
	"    // 关联模型\n"
	"    protected $relation = [];\n"
	"\n"
	"    // 保存自动完成列表\n"
	"    protected $auto = [];\n"
	"    // 新增自动完成列表\n"
	"    protected $insert = [];\n"
	"    // 更新自动完成列表\n"
	"    protected $update = [];\n"
	"    // 是否需要自动写入时间戳 如果设置为字符串 则表示时间字段的类型\n"
	"    protected $autoWriteTimestamp;\n"
	"    // 创建时间字段\n"
	"    protected $createTime = \'create_time\';\n"
	"    // 更新时间字段\n"
	"    protected $updateTime = \'update_time\';\n"
	"    // 时间字段取出后的默认时间格式\n"
	"    protected $dateFormat;\n"
	"    // 字段类型或者格式转换\n"
	"    protected $type = [];\n"
	"    // 是否为更新数据\n"
	"    protected $isUpdate = false;\n"
	"    // 是否使用Replace\n"
	"    protected $replace = false;\n"
	"    // 是否强制更新所有数据\n"
	"    protected $force = false;\n"
	"    // 更新条件\n"
	"    protected $updateWhere;\n"
	"    // 验证失败是否抛出异常\n"
	"    protected $failException = false;\n"
	"    // 全局查询范围\n"
	"    protected $useGlobalScope = true;\n"
	"    // 是否采用批量验证\n"
	"    protected $batchValidate = false;\n"
	"    // 查询数据集对象\n"
	"    protected $resultSetType;\n"
	"    // 关联自动写入\n"
	"    protected $relationWrite;\n"
	"\n"
	"    /**\n"
	"     * 初始化过的模型.\n"
	"     *\n"
	"     * @var array\n"
	"     */\n"
	"    protected static $initialized = [];\n"
	"\n"
	"    /**\n"
	"     * 是否从主库读取（主从分布式有效）\n"
	"     * @var array\n"
	"     */\n"
	"    protected static $readMaster;\n"
	"\n"
	"    /**\n"
	"     * 构造方法\n"
	"     * @access public\n"
	"     * @param array|object $data 数据\n"
	"     */\n"
	"    public function __construct($data = [])\n"
	"    {\n"
	"        if (is_object($data)) {\n"
	"            $this->data = get_object_vars($data);\n"
	"        } else {\n"
	"            $this->data = $data;\n"
	"        }\n"
	"\n"
	"        if ($this->disuse) {\n"
	"            // 废弃字段\n"
	"            foreach ((array) $this->disuse as $key) {\n"
	"                if (array_key_exists($key, $this->data)) {\n"
	"                    unset($this->data[$key]);\n"
	"                }\n"
	"            }\n"
	"        }\n"
	"\n"
	"        // 记录原始数据\n"
	"        $this->origin = $this->data;\n"
	"\n"
	"        // 当前类名\n"
	"        $this->class = get_called_class();\n"
	"\n"
	"        if (empty($this->name)) {\n"
	"            // 当前模型名\n"
	"            $name       = str_replace(\'\\\\\', \'/\', $this->class);\n"
	"            $this->name = basename($name);\n"
	"            if (Config::get(\'class_suffix\')) {\n"
	"                $suffix     = basename(dirname($name));\n"
	"                $this->name = substr($this->name, 0, -strlen($suffix));\n"
	"            }\n"
	"        }\n"
	"\n"
	"        if (is_null($this->autoWriteTimestamp)) {\n"
	"            // 自动写入时间戳\n"
	"            $this->autoWriteTimestamp = $this->getQuery()->getConfig(\'auto_timestamp\');\n"
	"        }\n"
	"\n"
	"        if (is_null($this->dateFormat)) {\n"
	"            // 设置时间戳格式\n"
	"            $this->dateFormat = $this->getQuery()->getConfig(\'datetime_format\');\n"
	"        }\n"
	"\n"
	"        if (is_null($this->resultSetType)) {\n"
	"            $this->resultSetType = $this->getQuery()->getConfig(\'resultset_type\');\n"
	"        }\n"
	"        // 执行初始化操作\n"
	"        $this->initialize();\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 是否从主库读取数据（主从分布有效）\n"
	"     * @access public\n"
	"     * @param  bool     $all 是否所有模型生效\n"
	"     * @return $this\n"
	"     */\n"
	"    public function readMaster($all = false)\n"
	"    {\n"
	"        $model = $all ? \'*\' : $this->class;\n"
	"\n"
	"        static::$readMaster[$model] = true;\n"
	"        return $this;\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 创建模型的查询对象\n"
	"     * @access protected\n"
	"     * @return Query\n"
	"     */\n"
	"    protected function buildQuery()\n"
	"    {\n"
	"        // 合并数据库配置\n"
	"        if (!empty($this->connection)) {\n"
	"            if (is_array($this->connection)) {\n"
	"                $connection = array_merge(Config::get(\'database\'), $this->connection);\n"
	"            } else {\n"
	"                $connection = $this->connection;\n"
	"            }\n"
	"        } else {\n"
	"            $connection = [];\n"
	"        }\n"
	"\n"
	"        $con = Db::connect($connection);\n"
	"        // 设置当前模型 确保查询返回模型对象\n"
	"        $queryClass = $this->query ?: $con->getConfig(\'query\');\n"
	"        $query      = new $queryClass($con, $this);\n"
	"\n"
	"        if (isset(static::$readMaster[\'*\']) || isset(static::$readMaster[$this->class])) {\n"
	"            $query->master(true);\n"
	"        }\n"
	"\n"
	"        // 设置当前数据表和模型名\n"
	"        if (!empty($this->table)) {\n"
	"            $query->setTable($this->table);\n"
	"        } else {\n"
	"            $query->name($this->name);\n"
	"        }\n"
	"\n"
	"        if (!empty($this->pk)) {\n"
	"            $query->pk($this->pk);\n"
	"        }\n"
	"\n"
	"        return $query;\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 创建新的模型实例\n"
	"     * @access public\n"
	"     * @param  array|object $data 数据\n"
	"     * @param  bool         $isUpdate 是否为更新\n"
	"     * @param  mixed        $where 更新条件\n"
	"     * @return Model\n"
	"     */\n"
	"    public function newInstance($data = [], $isUpdate = false, $where = null)\n"
	"    {\n"
	"        return (new static($data))->isUpdate($isUpdate, $where);\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 获取当前模型的查询对象\n"
	"     * @access public\n"
	"     * @param bool      $buildNewQuery  创建新的查询对象\n"
	"     * @return Query\n"
	"     */\n"
	"    public function getQuery($buildNewQuery = false)\n"
	"    {\n"
	"        if ($buildNewQuery) {\n"
	"            return $this->buildQuery();\n"
	"        } elseif (!isset(self::$links[$this->class])) {\n"
	"            // 创建模型查询对象\n"
	"            self::$links[$this->class] = $this->buildQuery();\n"
	"        }\n"
	"\n"
	"        return self::$links[$this->class];\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 获取当前模型的数据库查询对象\n"
	"     * @access public\n"
	"     * @param bool $useBaseQuery 是否调用全局查询范围\n"
	"     * @param bool $buildNewQuery 创建新的查询对象\n"
	"     * @return Query\n"
	"     */\n"
	"    public function db($useBaseQuery = true, $buildNewQuery = true)\n"
	"    {\n"
	"        $query = $this->getQuery($buildNewQuery);\n"
	"\n"
	"        // 全局作用域\n"
	"        if ($useBaseQuery && method_exists($this, \'base\')) {\n"
	"            call_user_func_array([$this, \'base\'], [ & $query]);\n"
	"        }\n"
	"\n"
	"        // 返回当前模型的数据库查询对象\n"
	"        return $query;\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     *  初始化模型\n"
	"     * @access protected\n"
	"     * @return void\n"
	"     */\n"
	"    protected function initialize()\n"
	"    {\n"
	"        $class = get_class($this);\n"
	"        if (!isset(static::$initialized[$class])) {\n"
	"            static::$initialized[$class] = true;\n"
	"            static::init();\n"
	"        }\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 初始化处理\n"
	"     * @access protected\n"
	"     * @return void\n"
	"     */\n"
	"    protected static function init()\n"
	"    {\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 设置父关联对象\n"
	"     * @access public\n"
	"     * @param Model $model  模型对象\n"
	"     * @return $this\n"
	"     */\n"
	"    public function setParent($model)\n"
	"    {\n"
	"        $this->parent = $model;\n"
	"        return $this;\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 获取父关联对象\n"
	"     * @access public\n"
	"     * @return Model\n"
	"     */\n"
	"    public function getParent()\n"
	"    {\n"
	"        return $this->parent;\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 设置数据对象值\n"
	"     * @access public\n"
	"     * @param mixed $data  数据或者属性名\n"
	"     * @param mixed $value 值\n"
	"     * @return $this\n"
	"     */\n"
	"    public function data($data, $value = null)\n"
	"    {\n"
	"        if (is_string($data)) {\n"
	"            $this->data[$data] = $value;\n"
	"        } else {\n"
	"            // 清空数据\n"
	"            $this->data = [];\n"
	"            if (is_object($data)) {\n"
	"                $data = get_object_vars($data);\n"
	"            }\n"
	"            if (true === $value) {\n"
	"                // 数据对象赋值\n"
	"                foreach ($data as $key => $value) {\n"
	"                    $this->setAttr($key, $value, $data);\n"
	"                }\n"
	"            } else {\n"
	"                $this->data = $data;\n"
	"            }\n"
	"        }\n"
	"        return $this;\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 获取对象原始数据 如果不存在指定字段返回false\n"
	"     * @access public\n"
	"     * @param string $name 字段名 留空获取全部\n"
	"     * @return mixed\n"
	"     * @throws InvalidArgumentException\n"
	"     */\n"
	"    public function getData($name = null)\n"
	"    {\n"
	"        if (is_null($name)) {\n"
	"            return $this->data;\n"
	"        } elseif (array_key_exists($name, $this->data)) {\n"
	"            return $this->data[$name];\n"
	"        } elseif (array_key_exists($name, $this->relation)) {\n"
	"            return $this->relation[$name];\n"
	"        } else {\n"
	"            throw new InvalidArgumentException(\'property not exists:\' . $this->class . \'->\' . $name);\n"
	"        }\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 是否需要自动写入时间字段\n"
	"     * @access public\n"
	"     * @param bool $auto\n"
	"     * @return $this\n"
	"     */\n"
	"    public function isAutoWriteTimestamp($auto)\n"
	"    {\n"
	"        $this->autoWriteTimestamp = $auto;\n"
	"        return $this;\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 更新是否强制写入数据 而不做比较\n"
	"     * @access public\n"
	"     * @param bool $force\n"
	"     * @return $this\n"
	"     */\n"
	"    public function force($force = true)\n"
	"    {\n"
	"        $this->force = $force;\n"
	"        return $this;\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 修改器 设置数据对象值\n"
	"     * @access public\n"
	"     * @param string $name  属性名\n"
	"     * @param mixed  $value 属性值\n"
	"     * @param array  $data  数据\n"
	"     * @return $this\n"
	"     */\n"
	"    public function setAttr($name, $value, $data = [])\n"
	"    {\n"
	"        if (is_null($value) && $this->autoWriteTimestamp && in_array($name, [$this->createTime, $this->updateTime])) {\n"
	"            // 自动写入的时间戳字段\n"
	"            $value = $this->autoWriteTimestamp($name);\n"
	"        } else {\n"
	"            // 检测修改器\n"
	"            $method = \'set\' . Loader::parseName($name, 1) . \'Attr\';\n"
	"            if (method_exists($this, $method)) {\n"
	"                $value = $this->$method($value, array_merge($this->data, $data), $this->relation);\n"
	"            } elseif (isset($this->type[$name])) {\n"
	"                // 类型转换\n"
	"                $value = $this->writeTransform($value, $this->type[$name]);\n"
	"            }\n"
	"        }\n"
	"\n"
	"        // 设置数据对象属性\n"
	"        $this->data[$name] = $value;\n"
	"        return $this;\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 获取当前模型的关联模型数据\n"
	"     * @access public\n"
	"     * @param string $name 关联方法名\n"
	"     * @return mixed\n"
	"     */\n"
	"    public function getRelation($name = null)\n"
	"    {\n"
	"        if (is_null($name)) {\n"
	"            return $this->relation;\n"
	"        } elseif (array_key_exists($name, $this->relation)) {\n"
	"            return $this->relation[$name];\n"
	"        } else {\n"
	"            return;\n"
	"        }\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 设置关联数据对象值\n"
	"     * @access public\n"
	"     * @param string $name  属性名\n"
	"     * @param mixed  $value 属性值\n"
	"     * @return $this\n"
	"     */\n"
	"    public function setRelation($name, $value)\n"
	"    {\n"
	"        $this->relation[$name] = $value;\n"
	"        return $this;\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 自动写入时间戳\n"
	"     * @access public\n"
	"     * @param string $name 时间戳字段\n"
	"     * @return mixed\n"
	"     */\n"
	"    protected function autoWriteTimestamp($name)\n"
	"    {\n"
	"        if (isset($this->type[$name])) {\n"
	"            $type = $this->type[$name];\n"
	"            if (strpos($type, \':\')) {\n"
	"                list($type, $param) = explode(\':\', $type, 2);\n"
	"            }\n"
	"            switch ($type) {\n"
	"                case \'datetime\':\n"
	"                case \'date\':\n"
	"                    $format = !empty($param) ? $param : $this->dateFormat;\n"
	"                    $value  = $this->formatDateTime(time(), $format);\n"
	"                    break;\n"
	"                case \'timestamp\':\n"
	"                case \'integer\':\n"
	"                default:\n"
	"                    $value = time();\n"
	"                    break;\n"
	"            }\n"
	"        } elseif (is_string($this->autoWriteTimestamp) && in_array(strtolower($this->autoWriteTimestamp), [\n"
	"            \'datetime\',\n"
	"            \'date\',\n"
	"            \'timestamp\',\n"
	"        ])\n"
	"        ) {\n"
	"            $value = $this->formatDateTime(time(), $this->dateFormat);\n"
	"        } else {\n"
	"            $value = $this->formatDateTime(time(), $this->dateFormat, true);\n"
	"        }\n"
	"        return $value;\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 时间日期字段格式化处理\n"
	"     * @access public\n"
	"     * @param mixed $time      时间日期表达式\n"
	"     * @param mixed $format    日期格式\n"
	"     * @param bool  $timestamp 是否进行时间戳转换\n"
	"     * @return mixed\n"
	"     */\n"
	"    protected function formatDateTime($time, $format, $timestamp = false)\n"
	"    {\n"
	"        if (false !== strpos($format, \'\\\\\')) {\n"
	"            $time = new $format($time);\n"
	"        } elseif (!$timestamp && false !== $format) {\n"
	"            $time = date($format, $time);\n"
	"        }\n"
	"        return $time;\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 数据写入 类型转换\n"
	"     * @access public\n"
	"     * @param mixed        $value 值\n"
	"     * @param string|array $type  要转换的类型\n"
	"     * @return mixed\n"
	"     */\n"
	"    protected function writeTransform($value, $type)\n"
	"    {\n"
	"        if (is_null($value)) {\n"
	"            return;\n"
	"        }\n"
	"\n"
	"        if (is_array($type)) {\n"
	"            list($type, $param) = $type;\n"
	"        } elseif (strpos($type, \':\')) {\n"
	"            list($type, $param) = explode(\':\', $type, 2);\n"
	"        }\n"
	"        switch ($type) {\n"
	"            case \'integer\':\n"
	"                $value = (int) $value;\n"
	"                break;\n"
	"            case \'float\':\n"
	"                if (empty($param)) {\n"
	"                    $value = (float) $value;\n"
	"                } else {\n"
	"                    $value = (float) number_format($value, $param, \'.\', \'\');\n"
	"                }\n"
	"                break;\n"
	"            case \'boolean\':\n"
	"                $value = (bool) $value;\n"
	"                break;\n"
	"            case \'timestamp\':\n"
	"                if (!is_numeric($value)) {\n"
	"                    $value = strtotime($value);\n"
	"                }\n"
	"                break;\n"
	"            case \'datetime\':\n"
	"                $format = !empty($param) ? $param : $this->dateFormat;\n"
	"                $value  = is_numeric($value) ? $value : strtotime($value);\n"
	"                $value  = $this->formatDateTime($value, $format);\n"
	"                break;\n"
	"            case \'object\':\n"
	"                if (is_object($value)) {\n"
	"                    $value = json_encode($value, JSON_FORCE_OBJECT);\n"
	"                }\n"
	"                break;\n"
	"            case \'array\':\n"
	"                $value = (array) $value;\n"
	"            case \'json\':\n"
	"                $option = !empty($param) ? (int) $param : JSON_UNESCAPED_UNICODE;\n"
	"                $value  = json_encode($value, $option);\n"
	"                break;\n"
	"            case \'serialize\':\n"
	"                $value = serialize($value);\n"
	"                break;\n"
	"\n"
	"        }\n"
	"        return $value;\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 获取器 获取数据对象的值\n"
	"     * @access public\n"
	"     * @param string $name 名称\n"
	"     * @return mixed\n"
	"     * @throws InvalidArgumentException\n"
	"     */\n"
	"    public function getAttr($name)\n"
	"    {\n"
	"        try {\n"
	"            $notFound = false;\n"
	"            $value    = $this->getData($name);\n"
	"        } catch (InvalidArgumentException $e) {\n"
	"            $notFound = true;\n"
	"            $value    = null;\n"
	"        }\n"
	"\n"
	"        // 检测属性获取器\n"
	"        $method = \'get\' . Loader::parseName($name, 1) . \'Attr\';\n"
	"        if (method_exists($this, $method)) {\n"
	"            $value = $this->$method($value, $this->data, $this->relation);\n"
	"        } elseif (isset($this->type[$name])) {\n"
	"            // 类型转换\n"
	"            $value = $this->readTransform($value, $this->type[$name]);\n"
	"        } elseif (in_array($name, [$this->createTime, $this->updateTime])) {\n"
	"            if (is_string($this->autoWriteTimestamp) && in_array(strtolower($this->autoWriteTimestamp), [\n"
	"                \'datetime\',\n"
	"                \'date\',\n"
	"                \'timestamp\',\n"
	"            ])\n"
	"            ) {\n"
	"                $value = $this->formatDateTime(strtotime($value), $this->dateFormat);\n"
	"            } else {\n"
	"                $value = $this->formatDateTime($value, $this->dateFormat);\n"
	"            }\n"
	"        } elseif ($notFound) {\n"
	"            $relation = Loader::parseName($name, 1, false);\n"
	"            if (method_exists($this, $relation)) {\n"
	"                $modelRelation = $this->$relation();\n"
	"                // 不存在该字段 获取关联数据\n"
	"                $value = $this->getRelationData($modelRelation);\n"
	"                // 保存关联对象值\n"
	"                $this->relation[$name] = $value;\n"
	"            } else {\n"
	"                throw new InvalidArgumentException(\'property not exists:\' . $this->class . \'->\' . $name);\n"
	"            }\n"
	"        }\n"
	"        return $value;\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 获取关联模型数据\n"
	"     * @access public\n"
	"     * @param Relation        $modelRelation 模型关联对象\n"
	"     * @return mixed\n"
	"     * @throws BadMethodCallException\n"
	"     */\n"
	"    protected function getRelationData(Relation $modelRelation)\n"
	"    {\n"
	"        if ($this->parent && !$modelRelation->isSelfRelation() && get_class($modelRelation->getModel()) == get_class($this->parent)) {\n"
	"            $value = $this->parent;\n"
	"        } else {\n"
	"            // 首先获取关联数据\n"
	"            if (method_exists($modelRelation, \'getRelation\')) {\n"
	"                $value = $modelRelation->getRelation();\n"
	"            } else {\n"
	"                throw new BadMethodCallException(\'method not exists:\' . get_class($modelRelation) . \'-> getRelation\');\n"
	"            }\n"
	"        }\n"
	"        return $value;\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 数据读取 类型转换\n"
	"     * @access public\n"
	"     * @param mixed        $value 值\n"
	"     * @param string|array $type  要转换的类型\n"
	"     * @return mixed\n"
	"     */\n"
	"    protected function readTransform($value, $type)\n"
	"    {\n"
	"        if (is_null($value)) {\n"
	"            return;\n"
	"        }\n"
	"\n"
	"        if (is_array($type)) {\n"
	"            list($type, $param) = $type;\n"
	"        } elseif (strpos($type, \':\')) {\n"
	"            list($type, $param) = explode(\':\', $type, 2);\n"
	"        }\n"
	"        switch ($type) {\n"
	"            case \'integer\':\n"
	"                $value = (int) $value;\n"
	"                break;\n"
	"            case \'float\':\n"
	"                if (empty($param)) {\n"
	"                    $value = (float) $value;\n"
	"                } else {\n"
	"                    $value = (float) number_format($value, $param, \'.\', \'\');\n"
	"                }\n"
	"                break;\n"
	"            case \'boolean\':\n"
	"                $value = (bool) $value;\n"
	"                break;\n"
	"            case \'timestamp\':\n"
	"                if (!is_null($value)) {\n"
	"                    $format = !empty($param) ? $param : $this->dateFormat;\n"
	"                    $value  = $this->formatDateTime($value, $format);\n"
	"                }\n"
	"                break;\n"
	"            case \'datetime\':\n"
	"                if (!is_null($value)) {\n"
	"                    $format = !empty($param) ? $param : $this->dateFormat;\n"
	"                    $value  = $this->formatDateTime(strtotime($value), $format);\n"
	"                }\n"
	"                break;\n"
	"            case \'json\':\n"
	"                $value = json_decode($value, true);\n"
	"                break;\n"
	"            case \'array\':\n"
	"                $value = empty($value) ? [] : json_decode($value, true);\n"
	"                break;\n"
	"            case \'object\':\n"
	"                $value = empty($value) ? new \\stdClass() : json_decode($value);\n"
	"                break;\n"
	"            case \'serialize\':\n"
	"                try {\n"
	"                    $value = unserialize($value);\n"
	"                } catch (\\Exception $e) {\n"
	"                    $value = null;\n"
	"                }\n"
	"                break;\n"
	"            default:\n"
	"                if (false !== strpos($type, \'\\\\\')) {\n"
	"                    // 对象类型\n"
	"                    $value = new $type($value);\n"
	"                }\n"
	"        }\n"
	"        return $value;\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 设置需要追加的输出属性\n"
	"     * @access public\n"
	"     * @param array $append   属性列表\n"
	"     * @param bool  $override 是否覆盖\n"
	"     * @return $this\n"
	"     */\n"
	"    public function append($append = [], $override = false)\n"
	"    {\n"
	"        $this->append = $override ? $append : array_merge($this->append, $append);\n"
	"        return $this;\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 设置附加关联对象的属性\n"
	"     * @access public\n"
	"     * @param string       $relation 关联方法\n"
	"     * @param string|array $append   追加属性名\n"
	"     * @return $this\n"
	"     * @throws Exception\n"
	"     */\n"
	"    public function appendRelationAttr($relation, $append)\n"
	"    {\n"
	"        if (is_string($append)) {\n"
	"            $append = explode(\',\', $append);\n"
	"        }\n"
	"\n"
	"        $relation = Loader::parseName($relation, 1, false);\n"
	"\n"
	"        // 获取关联数据\n"
	"        if (isset($this->relation[$relation])) {\n"
	"            $model = $this->relation[$relation];\n"
	"        } else {\n"
	"            $model = $this->getRelationData($this->$relation());\n"
	"        }\n"
	"\n"
	"        if ($model instanceof Model) {\n"
	"            foreach ($append as $key => $attr) {\n"
	"                $key = is_numeric($key) ? $attr : $key;\n"
	"                if (isset($this->data[$key])) {\n"
	"                    throw new Exception(\'bind attr has exists:\' . $key);\n"
	"                } else {\n"
	"                    $this->data[$key] = $model->getAttr($attr);\n"
	"                }\n"
	"            }\n"
	"        }\n"
	"        return $this;\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 设置需要隐藏的输出属性\n"
	"     * @access public\n"
	"     * @param array $hidden   属性列表\n"
	"     * @param bool  $override 是否覆盖\n"
	"     * @return $this\n"
	"     */\n"
	"    public function hidden($hidden = [], $override = false)\n"
	"    {\n"
	"        $this->hidden = $override ? $hidden : array_merge($this->hidden, $hidden);\n"
	"        return $this;\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 设置需要输出的属性\n"
	"     * @access public\n"
	"     * @param array $visible\n"
	"     * @param bool  $override 是否覆盖\n"
	"     * @return $this\n"
	"     */\n"
	"    public function visible($visible = [], $override = false)\n"
	"    {\n"
	"        $this->visible = $override ? $visible : array_merge($this->visible, $visible);\n"
	"        return $this;\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 解析隐藏及显示属性\n"
	"     * @access protected\n"
	"     * @param array $attrs  属性\n"
	"     * @param array $result 结果集\n"
	"     * @param bool  $visible\n"
	"     * @return array\n"
	"     */\n"
	"    protected function parseAttr($attrs, &$result, $visible = true)\n"
	"    {\n"
	"        $array = [];\n"
	"        foreach ($attrs as $key => $val) {\n"
	"            if (is_array($val)) {\n"
	"                if ($visible) {\n"
	"                    $array[] = $key;\n"
	"                }\n"
	"                $result[$key] = $val;\n"
	"            } elseif (strpos($val, \'.\')) {\n"
	"                list($key, $name) = explode(\'.\', $val);\n"
	"                if ($visible) {\n"
	"                    $array[] = $key;\n"
	"                }\n"
	"                $result[$key][] = $name;\n"
	"            } else {\n"
	"                $array[] = $val;\n"
	"            }\n"
	"        }\n"
	"        return $array;\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 转换子模型对象\n"
	"     * @access protected\n"
	"     * @param Model|ModelCollection $model\n"
	"     * @param                  $visible\n"
	"     * @param                  $hidden\n"
	"     * @param                  $key\n"
	"     * @return array\n"
	"     */\n"
	"    protected function subToArray($model, $visible, $hidden, $key)\n"
	"    {\n"
	"        // 关联模型对象\n"
	"        if (isset($visible[$key])) {\n"
	"            $model->visible($visible[$key]);\n"
	"        } elseif (isset($hidden[$key])) {\n"
	"            $model->hidden($hidden[$key]);\n"
	"        }\n"
	"        return $model->toArray();\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 转换当前模型对象为数组\n"
	"     * @access public\n"
	"     * @return array\n"
	"     */\n"
	"    public function toArray()\n"
	"    {\n"
	"        $item    = [];\n"
	"        $visible = [];\n"
	"        $hidden  = [];\n"
	"\n"
	"        $data = array_merge($this->data, $this->relation);\n"
	"\n"
	"        // 过滤属性\n"
	"        if (!empty($this->visible)) {\n"
	"            $array = $this->parseAttr($this->visible, $visible);\n"
	"            $data  = array_intersect_key($data, array_flip($array));\n"
	"        } elseif (!empty($this->hidden)) {\n"
	"            $array = $this->parseAttr($this->hidden, $hidden, false);\n"
	"            $data  = array_diff_key($data, array_flip($array));\n"
	"        }\n"
	"\n"
	"        foreach ($data as $key => $val) {\n"
	"            if ($val instanceof Model || $val instanceof ModelCollection) {\n"
	"                // 关联模型对象\n"
	"                $item[$key] = $this->subToArray($val, $visible, $hidden, $key);\n"
	"            } elseif (is_array($val) && reset($val) instanceof Model) {\n"
	"                // 关联模型数据集\n"
	"                $arr = [];\n"
	"                foreach ($val as $k => $value) {\n"
	"                    $arr[$k] = $this->subToArray($value, $visible, $hidden, $key);\n"
	"                }\n"
	"                $item[$key] = $arr;\n"
	"            } else {\n"
	"                // 模型属性\n"
	"                $item[$key] = $this->getAttr($key);\n"
	"            }\n"
	"        }\n"
	"        // 追加属性（必须定义获取器）\n"
	"        if (!empty($this->append)) {\n"
	"            foreach ($this->append as $key => $name) {\n"
	"                if (is_array($name)) {\n"
	"                    // 追加关联对象属性\n"
	"                    $relation   = $this->getAttr($key);\n"
	"                    $item[$key] = $relation->append($name)->toArray();\n"
	"                } elseif (strpos($name, \'.\')) {\n"
	"                    list($key, $attr) = explode(\'.\', $name);\n"
	"                    // 追加关联对象属性\n"
	"                    $relation   = $this->getAttr($key);\n"
	"                    $item[$key] = $relation->append([$attr])->toArray();\n"
	"                } else {\n"
	"                    $relation = Loader::parseName($name, 1, false);\n"
	"                    if (method_exists($this, $relation)) {\n"
	"                        $modelRelation = $this->$relation();\n"
	"                        $value         = $this->getRelationData($modelRelation);\n"
	"\n"
	"                        if (method_exists($modelRelation, \'getBindAttr\')) {\n"
	"                            $bindAttr = $modelRelation->getBindAttr();\n"
	"                            if ($bindAttr) {\n"
	"                                foreach ($bindAttr as $key => $attr) {\n"
	"                                    $key = is_numeric($key) ? $attr : $key;\n"
	"                                    if (isset($this->data[$key])) {\n"
	"                                        throw new Exception(\'bind attr has exists:\' . $key);\n"
	"                                    } else {\n"
	"                                        $item[$key] = $value ? $value->getAttr($attr) : null;\n"
	"                                    }\n"
	"                                }\n"
	"                                continue;\n"
	"                            }\n"
	"                        }\n"
	"                        $item[$name] = $value;\n"
	"                    } else {\n"
	"                        $item[$name] = $this->getAttr($name);\n"
	"                    }\n"
	"                }\n"
	"            }\n"
	"        }\n"
	"        return !empty($item) ? $item : [];\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 转换当前模型对象为JSON字符串\n"
	"     * @access public\n"
	"     * @param integer $options json参数\n"
	"     * @return string\n"
	"     */\n"
	"    public function toJson($options = JSON_UNESCAPED_UNICODE)\n"
	"    {\n"
	"        return json_encode($this->toArray(), $options);\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 移除当前模型的关联属性\n"
	"     * @access public\n"
	"     * @return $this\n"
	"     */\n"
	"    public function removeRelation()\n"
	"    {\n"
	"        $this->relation = [];\n"
	"        return $this;\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 转换当前模型数据集为数据集对象\n"
	"     * @access public\n"
	"     * @param array|\\think\\Collection $collection 数据集\n"
	"     * @return \\think\\Collection\n"
	"     */\n"
	"    public function toCollection($collection)\n"
	"    {\n"
	"        if ($this->resultSetType) {\n"
	"            if (\'collection\' == $this->resultSetType) {\n"
	"                $collection = new ModelCollection($collection);\n"
	"            } elseif (false !== strpos($this->resultSetType, \'\\\\\')) {\n"
	"                $class      = $this->resultSetType;\n"
	"                $collection = new $class($collection);\n"
	"            }\n"
	"        }\n"
	"        return $collection;\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 关联数据一起更新\n"
	"     * @access public\n"
	"     * @param mixed $relation 关联\n"
	"     * @return $this\n"
	"     */\n"
	"    public function together($relation)\n"
	"    {\n"
	"        if (is_string($relation)) {\n"
	"            $relation = explode(\',\', $relation);\n"
	"        }\n"
	"        $this->relationWrite = $relation;\n"
	"        return $this;\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 获取模型对象的主键\n"
	"     * @access public\n"
	"     * @param string $name 模型名\n"
	"     * @return mixed\n"
	"     */\n"
	"    public function getPk($name = \'\')\n"
	"    {\n"
	"        if (!empty($name)) {\n"
	"            $table = $this->getQuery()->getTable($name);\n"
	"            return $this->getQuery()->getPk($table);\n"
	"        } elseif (empty($this->pk)) {\n"
	"            $this->pk = $this->getQuery()->getPk();\n"
	"        }\n"
	"        return $this->pk;\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 判断一个字段名是否为主键字段\n"
	"     * @access public\n"
	"     * @param string $key 名称\n"
	"     * @return bool\n"
	"     */\n"
	"    protected function isPk($key)\n"
	"    {\n"
	"        $pk = $this->getPk();\n"
	"        if (is_string($pk) && $pk == $key) {\n"
	"            return true;\n"
	"        } elseif (is_array($pk) && in_array($key, $pk)) {\n"
	"            return true;\n"
	"        }\n"
	"        return false;\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 新增数据是否使用Replace\n"
	"     * @access public\n"
	"     * @param  bool $replace\n"
	"     * @return $this\n"
	"     */\n"
	"    public function replace($replace = true)\n"
	"    {\n"
	"        $this->replace = $replace;\n"
	"        return $this;\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 保存当前数据对象\n"
	"     * @access public\n"
	"     * @param array  $data     数据\n"
	"     * @param array  $where    更新条件\n"
	"     * @param string $sequence 自增序列名\n"
	"     * @return integer|false\n"
	"     */\n"
	"    public function save($data = [], $where = [], $sequence = null)\n"
	"    {\n"
	"        if (is_string($data)) {\n"
	"            $sequence = $data;\n"
	"            $data     = [];\n"
	"        }\n"
	"\n"
	"        // 数据自动验证\n"
	"        if (!empty($data)) {\n"
	"            if (!$this->validateData($data)) {\n"
	"                return false;\n"
	"            }\n"
	"\n"
	"            // 数据对象赋值\n"
	"            foreach ($data as $key => $value) {\n"
	"                $this->setAttr($key, $value, $data);\n"
	"            }\n"
	"        }\n"
	"\n"
	"        if (!empty($where)) {\n"
	"            $this->isUpdate    = true;\n"
	"            $this->updateWhere = $where;\n"
	"        }\n"
	"\n"
	"        // 自动关联写入\n"
	"        if (!empty($this->relationWrite)) {\n"
	"            $relation = [];\n"
	"            foreach ($this->relationWrite as $key => $name) {\n"
	"                if (is_array($name)) {\n"
	"                    if (key($name) === 0) {\n"
	"                        $relation[$key] = [];\n"
	"                        foreach ($name as $val) {\n"
	"                            if (isset($this->data[$val])) {\n"
	"                                $relation[$key][$val] = $this->data[$val];\n"
	"                                unset($this->data[$val]);\n"
	"                            }\n"
	"                        }\n"
	"                    } else {\n"
	"                        $relation[$key] = $name;\n"
	"                    }\n"
	"                } elseif (isset($this->relation[$name])) {\n"
	"                    $relation[$name] = $this->relation[$name];\n"
	"                } elseif (isset($this->data[$name])) {\n"
	"                    $relation[$name] = $this->data[$name];\n"
	"                    unset($this->data[$name]);\n"
	"                }\n"
	"            }\n"
	"        }\n"
	"\n"
	"        // 数据自动完成\n"
	"        $this->autoCompleteData($this->auto);\n"
	"\n"
	"        // 事件回调\n"
	"        if (false === $this->trigger(\'before_write\', $this)) {\n"
	"            return false;\n"
	"        }\n"
	"        $pk = $this->getPk();\n"
	"        if ($this->isUpdate) {\n"
	"            // 自动更新\n"
	"            $this->autoCompleteData($this->update);\n"
	"\n"
	"            // 事件回调\n"
	"            if (false === $this->trigger(\'before_update\', $this)) {\n"
	"                return false;\n"
	"            }\n"
	"\n"
	"            // 获取有更新的数据\n"
	"            $data = $this->getChangedData();\n"
	"\n"
	"            if (empty($data) || (count($data) == 1 && is_string($pk) && isset($data[$pk]))) {\n"
	"                // 关联更新\n"
	"                if (isset($relation)) {\n"
	"                    $this->autoRelationUpdate($relation);\n"
	"                }\n"
	"                return 0;\n"
	"            } elseif ($this->autoWriteTimestamp && $this->updateTime && !isset($data[$this->updateTime])) {\n"
	"                // 自动写入更新时间\n"
	"                $data[$this->updateTime]       = $this->autoWriteTimestamp($this->updateTime);\n"
	"                $this->data[$this->updateTime] = $data[$this->updateTime];\n"
	"            }\n"
	"\n"
	"            if (empty($where) && !empty($this->updateWhere)) {\n"
	"                $where = $this->updateWhere;\n"
	"            }\n"
	"\n"
	"            // 保留主键数据\n"
	"            foreach ($this->data as $key => $val) {\n"
	"                if ($this->isPk($key)) {\n"
	"                    $data[$key] = $val;\n"
	"                }\n"
	"            }\n"
	"\n"
	"            $array = [];\n"
	"\n"
	"            foreach ((array) $pk as $key) {\n"
	"                if (isset($data[$key])) {\n"
	"                    $array[$key] = $data[$key];\n"
	"                    unset($data[$key]);\n"
	"                }\n"
	"            }\n"
	"\n"
	"            if (!empty($array)) {\n"
	"                $where = $array;\n"
	"            }\n"
	"\n"
	"            // 检测字段\n"
	"            $allowFields = $this->checkAllowField(array_merge($this->auto, $this->update));\n"
	"\n"
	"            // 模型更新\n"
	"            if (!empty($allowFields)) {\n"
	"                $result = $this->getQuery()->where($where)->strict(false)->field($allowFields)->update($data);\n"
	"            } else {\n"
	"                $result = $this->getQuery()->where($where)->update($data);\n"
	"            }\n"
	"\n"
	"            // 关联更新\n"
	"            if (isset($relation)) {\n"
	"                $this->autoRelationUpdate($relation);\n"
	"            }\n"
	"\n"
	"            // 更新回调\n"
	"            $this->trigger(\'after_update\', $this);\n"
	"\n"
	"        } else {\n"
	"            // 自动写入\n"
	"            $this->autoCompleteData($this->insert);\n"
	"\n"
	"            // 自动写入创建时间和更新时间\n"
	"            if ($this->autoWriteTimestamp) {\n"
	"                if ($this->createTime && !isset($this->data[$this->createTime])) {\n"
	"                    $this->data[$this->createTime] = $this->autoWriteTimestamp($this->createTime);\n"
	"                }\n"
	"                if ($this->updateTime && !isset($this->data[$this->updateTime])) {\n"
	"                    $this->data[$this->updateTime] = $this->autoWriteTimestamp($this->updateTime);\n"
	"                }\n"
	"            }\n"
	"\n"
	"            if (false === $this->trigger(\'before_insert\', $this)) {\n"
	"                return false;\n"
	"            }\n"
	"\n"
	"            // 检测字段\n"
	"            $allowFields = $this->checkAllowField(array_merge($this->auto, $this->insert));\n"
	"            if (!empty($allowFields)) {\n"
	"                $result = $this->getQuery()->strict(false)->field($allowFields)->insert($this->data, $this->replace, false, $sequence);\n"
	"            } else {\n"
	"                $result = $this->getQuery()->insert($this->data, $this->replace, false, $sequence);\n"
	"            }\n"
	"\n"
	"            // 获取自动增长主键\n"
	"            if ($result && $insertId = $this->getQuery()->getLastInsID($sequence)) {\n"
	"                foreach ((array) $pk as $key) {\n"
	"                    if (!isset($this->data[$key]) || \'\' == $this->data[$key]) {\n"
	"                        $this->data[$key] = $insertId;\n"
	"                    }\n"
	"                }\n"
	"            }\n"
	"\n"
	"            // 关联写入\n"
	"            if (isset($relation)) {\n"
	"                foreach ($relation as $name => $val) {\n"
	"                    $method = Loader::parseName($name, 1, false);\n"
	"                    $this->$method()->save($val);\n"
	"                }\n"
	"            }\n"
	"\n"
	"            // 标记为更新\n"
	"            $this->isUpdate = true;\n"
	"\n"
	"            // 新增回调\n"
	"            $this->trigger(\'after_insert\', $this);\n"
	"        }\n"
	"        // 写入回调\n"
	"        $this->trigger(\'after_write\', $this);\n"
	"\n"
	"        // 重新记录原始数据\n"
	"        $this->origin = $this->data;\n"
	"\n"
	"        return $result;\n"
	"    }\n"
	"\n"
	"    protected function checkAllowField($auto = [])\n"
	"    {\n"
	"        if (true === $this->field) {\n"
	"            $this->field = $this->getQuery()->getTableInfo(\'\', \'fields\');\n"
	"            $field       = $this->field;\n"
	"        } elseif (!empty($this->field)) {\n"
	"            $field = array_merge($this->field, $auto);\n"
	"            if ($this->autoWriteTimestamp) {\n"
	"                array_push($field, $this->createTime, $this->updateTime);\n"
	"            }\n"
	"        } elseif (!empty($this->except)) {\n"
	"            $fields      = $this->getQuery()->getTableInfo(\'\', \'fields\');\n"
	"            $field       = array_diff($fields, (array) $this->except);\n"
	"            $this->field = $field;\n"
	"        } else {\n"
	"            $field = [];\n"
	"        }\n"
	"\n"
	"        if ($this->disuse) {\n"
	"            // 废弃字段\n"
	"            $field = array_diff($field, (array) $this->disuse);\n"
	"        }\n"
	"        return $field;\n"
	"    }\n"
	"\n"
	"    protected function autoRelationUpdate($relation)\n"
	"    {\n"
	"        foreach ($relation as $name => $val) {\n"
	"            if ($val instanceof Model) {\n"
	"                $val->save();\n"
	"            } else {\n"
	"                unset($this->data[$name]);\n"
	"                $model = $this->getAttr($name);\n"
	"                if ($model instanceof Model) {\n"
	"                    $model->save($val);\n"
	"                }\n"
	"            }\n"
	"        }\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 获取变化的数据 并排除只读数据\n"
	"     * @access public\n"
	"     * @return array\n"
	"     */\n"
	"    public function getChangedData()\n"
	"    {\n"
	"        if ($this->force) {\n"
	"            $data = $this->data;\n"
	"        } else {\n"
	"            $data = array_udiff_assoc($this->data, $this->origin, function ($a, $b) {\n"
	"                if ((empty($a) || empty($b)) && $a !== $b) {\n"
	"                    return 1;\n"
	"                }\n"
	"                return is_object($a) || $a != $b ? 1 : 0;\n"
	"            });\n"
	"        }\n"
	"\n"
	"        if (!empty($this->readonly)) {\n"
	"            // 只读字段不允许更新\n"
	"            foreach ($this->readonly as $key => $field) {\n"
	"                if (isset($data[$field])) {\n"
	"                    unset($data[$field]);\n"
	"                }\n"
	"            }\n"
	"        }\n"
	"\n"
	"        return $data;\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 字段值(延迟)增长\n"
	"     * @access public\n"
	"     * @param string  $field    字段名\n"
	"     * @param integer $step     增长值\n"
	"     * @param integer $lazyTime 延时时间(s)\n"
	"     * @return integer|true\n"
	"     * @throws Exception\n"
	"     */\n"
	"    public function setInc($field, $step = 1, $lazyTime = 0)\n"
	"    {\n"
	"        // 更新条件\n"
	"        $where = $this->getWhere();\n"
	"\n"
	"        $result = $this->getQuery()->where($where)->setInc($field, $step, $lazyTime);\n"
	"        if (true !== $result) {\n"
	"            $this->data[$field] += $step;\n"
	"        }\n"
	"\n"
	"        return $result;\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 字段值(延迟)增长\n"
	"     * @access public\n"
	"     * @param string  $field    字段名\n"
	"     * @param integer $step     增长值\n"
	"     * @param integer $lazyTime 延时时间(s)\n"
	"     * @return integer|true\n"
	"     * @throws Exception\n"
	"     */\n"
	"    public function setDec($field, $step = 1, $lazyTime = 0)\n"
	"    {\n"
	"        // 更新条件\n"
	"        $where  = $this->getWhere();\n"
	"        $result = $this->getQuery()->where($where)->setDec($field, $step, $lazyTime);\n"
	"        if (true !== $result) {\n"
	"            $this->data[$field] -= $step;\n"
	"        }\n"
	"\n"
	"        return $result;\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 获取更新条件\n"
	"     * @access protected\n"
	"     * @return mixed\n"
	"     */\n"
	"    protected function getWhere()\n"
	"    {\n"
	"        // 删除条件\n"
	"        $pk = $this->getPk();\n"
	"\n"
	"        if (is_string($pk) && isset($this->data[$pk])) {\n"
	"            $where = [$pk => $this->data[$pk]];\n"
	"        } elseif (!empty($this->updateWhere)) {\n"
	"            $where = $this->updateWhere;\n"
	"        } else {\n"
	"            $where = null;\n"
	"        }\n"
	"        return $where;\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 保存多个数据到当前数据对象\n"
	"     * @access public\n"
	"     * @param array   $dataSet 数据\n"
	"     * @param boolean $replace 是否自动识别更新和写入\n"
	"     * @return array|false\n"
	"     * @throws \\Exception\n"
	"     */\n"
	"    public function saveAll($dataSet, $replace = true)\n"
	"    {\n"
	"        if ($this->validate) {\n"
	"            // 数据批量验证\n"
	"            $validate = $this->validate;\n"
	"            foreach ($dataSet as $data) {\n"
	"                if (!$this->validateData($data, $validate)) {\n"
	"                    return false;\n"
	"                }\n"
	"            }\n"
	"        }\n"
	"\n"
	"        $result = [];\n"
	"        $db     = $this->getQuery();\n"
	"        $db->startTrans();\n"
	"        try {\n"
	"            $pk = $this->getPk();\n"
	"            if (is_string($pk) && $replace) {\n"
	"                $auto = true;\n"
	"            }\n"
	"            foreach ($dataSet as $key => $data) {\n"
	"                if ($this->isUpdate || (!empty($auto) && isset($data[$pk]))) {\n"
	"                    $result[$key] = self::update($data, [], $this->field);\n"
	"                } else {\n"
	"                    $result[$key] = self::create($data, $this->field);\n"
	"                }\n"
	"            }\n"
	"            $db->commit();\n"
	"            return $this->toCollection($result);\n"
	"        } catch (\\Exception $e) {\n"
	"            $db->rollback();\n"
	"            throw $e;\n"
	"        }\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 设置允许写入的字段\n"
	"     * @access public\n"
	"     * @param string|array $field 允许写入的字段 如果为true只允许写入数据表字段\n"
	"     * @return $this\n"
	"     */\n"
	"    public function allowField($field)\n"
	"    {\n"
	"        if (is_string($field)) {\n"
	"            $field = explode(\',\', $field);\n"
	"        }\n"
	"        $this->field = $field;\n"
	"        return $this;\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 设置排除写入的字段\n"
	"     * @access public\n"
	"     * @param string|array $field 排除允许写入的字段\n"
	"     * @return $this\n"
	"     */\n"
	"    public function except($field)\n"
	"    {\n"
	"        if (is_string($field)) {\n"
	"            $field = explode(\',\', $field);\n"
	"        }\n"
	"        $this->except = $field;\n"
	"        return $this;\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 设置只读字段\n"
	"     * @access public\n"
	"     * @param mixed $field 只读字段\n"
	"     * @return $this\n"
	"     */\n"
	"    public function readonly($field)\n"
	"    {\n"
	"        if (is_string($field)) {\n"
	"            $field = explode(\',\', $field);\n"
	"        }\n"
	"        $this->readonly = $field;\n"
	"        return $this;\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 是否为更新数据\n"
	"     * @access public\n"
	"     * @param bool  $update\n"
	"     * @param mixed $where\n"
	"     * @return $this\n"
	"     */\n"
	"    public function isUpdate($update = true, $where = null)\n"
	"    {\n"
	"        $this->isUpdate = $update;\n"
	"        if (!empty($where)) {\n"
	"            $this->updateWhere = $where;\n"
	"        }\n"
	"        return $this;\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 数据自动完成\n"
	"     * @access public\n"
	"     * @param array $auto 要自动更新的字段列表\n"
	"     * @return void\n"
	"     */\n"
	"    protected function autoCompleteData($auto = [])\n"
	"    {\n"
	"        foreach ($auto as $field => $value) {\n"
	"            if (is_integer($field)) {\n"
	"                $field = $value;\n"
	"                $value = null;\n"
	"            }\n"
	"\n"
	"            if (!isset($this->data[$field])) {\n"
	"                $default = null;\n"
	"            } else {\n"
	"                $default = $this->data[$field];\n"
	"            }\n"
	"\n"
	"            $this->setAttr($field, !is_null($value) ? $value : $default);\n"
	"        }\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 删除当前的记录\n"
	"     * @access public\n"
	"     * @return integer\n"
	"     */\n"
	"    public function delete()\n"
	"    {\n"
	"        if (false === $this->trigger(\'before_delete\', $this)) {\n"
	"            return false;\n"
	"        }\n"
	"\n"
	"        // 删除条件\n"
	"        $where = $this->getWhere();\n"
	"\n"
	"        // 删除当前模型数据\n"
	"        $result = $this->getQuery()->where($where)->delete();\n"
	"\n"
	"        // 关联删除\n"
	"        if (!empty($this->relationWrite)) {\n"
	"            foreach ($this->relationWrite as $key => $name) {\n"
	"                $name  = is_numeric($key) ? $name : $key;\n"
	"                $model = $this->getAttr($name);\n"
	"                if ($model instanceof Model) {\n"
	"                    $model->delete();\n"
	"                }\n"
	"            }\n"
	"        }\n"
	"\n"
	"        $this->trigger(\'after_delete\', $this);\n"
	"        // 清空原始数据\n"
	"        $this->origin = [];\n"
	"\n"
	"        return $result;\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 设置自动完成的字段（ 规则通过修改器定义）\n"
	"     * @access public\n"
	"     * @param array $fields 需要自动完成的字段\n"
	"     * @return $this\n"
	"     */\n"
	"    public function auto($fields)\n"
	"    {\n"
	"        $this->auto = $fields;\n"
	"        return $this;\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 设置字段验证\n"
	"     * @access public\n"
	"     * @param array|string|bool $rule  验证规则 true表示自动读取验证器类\n"
	"     * @param array             $msg   提示信息\n"
	"     * @param bool              $batch 批量验证\n"
	"     * @return $this\n"
	"     */\n"
	"    public function validate($rule = true, $msg = [], $batch = false)\n"
	"    {\n"
	"        if (is_array($rule)) {\n"
	"            $this->validate = [\n"
	"                \'rule\' => $rule,\n"
	"                \'msg\'  => $msg,\n"
	"            ];\n"
	"        } else {\n"
	"            $this->validate = true === $rule ? $this->name : $rule;\n"
	"        }\n"
	"        $this->batchValidate = $batch;\n"
	"        return $this;\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 设置验证失败后是否抛出异常\n"
	"     * @access public\n"
	"     * @param bool $fail 是否抛出异常\n"
	"     * @return $this\n"
	"     */\n"
	"    public function validateFailException($fail = true)\n"
	"    {\n"
	"        $this->failException = $fail;\n"
	"        return $this;\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 自动验证数据\n"
	"     * @access protected\n"
	"     * @param array $data  验证数据\n"
	"     * @param mixed $rule  验证规则\n"
	"     * @param bool  $batch 批量验证\n"
	"     * @return bool\n"
	"     */\n"
	"    protected function validateData($data, $rule = null, $batch = null)\n"
	"    {\n"
	"        $info = is_null($rule) ? $this->validate : $rule;\n"
	"\n"
	"        if (!empty($info)) {\n"
	"            if (is_array($info)) {\n"
	"                $validate = Loader::validate();\n"
	"                $validate->rule($info[\'rule\']);\n"
	"                $validate->message($info[\'msg\']);\n"
	"            } else {\n"
	"                $name = is_string($info) ? $info : $this->name;\n"
	"                if (strpos($name, \'.\')) {\n"
	"                    list($name, $scene) = explode(\'.\', $name);\n"
	"                }\n"
	"                $validate = Loader::validate($name);\n"
	"                if (!empty($scene)) {\n"
	"                    $validate->scene($scene);\n"
	"                }\n"
	"            }\n"
	"            $batch = is_null($batch) ? $this->batchValidate : $batch;\n"
	"\n"
	"            if (!$validate->batch($batch)->check($data)) {\n"
	"                $this->error = $validate->getError();\n"
	"                if ($this->failException) {\n"
	"                    throw new ValidateException($this->error);\n"
	"                } else {\n"
	"                    return false;\n"
	"                }\n"
	"            }\n"
	"            $this->validate = null;\n"
	"        }\n"
	"        return true;\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 返回模型的错误信息\n"
	"     * @access public\n"
	"     * @return string|array\n"
	"     */\n"
	"    public function getError()\n"
	"    {\n"
	"        return $this->error;\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 注册回调方法\n"
	"     * @access public\n"
	"     * @param string   $event    事件名\n"
	"     * @param callable $callback 回调方法\n"
	"     * @param bool     $override 是否覆盖\n"
	"     * @return void\n"
	"     */\n"
	"    public static function event($event, $callback, $override = false)\n"
	"    {\n"
	"        $class = get_called_class();\n"
	"        if ($override) {\n"
	"            self::$event[$class][$event] = [];\n"
	"        }\n"
	"        self::$event[$class][$event][] = $callback;\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 触发事件\n"
	"     * @access protected\n"
	"     * @param string $event  事件名\n"
	"     * @param mixed  $params 传入参数（引用）\n"
	"     * @return bool\n"
	"     */\n"
	"    protected function trigger($event, &$params)\n"
	"    {\n"
	"        if (isset(self::$event[$this->class][$event])) {\n"
	"            foreach (self::$event[$this->class][$event] as $callback) {\n"
	"                if (is_callable($callback)) {\n"
	"                    $result = call_user_func_array($callback, [ & $params]);\n"
	"                    if (false === $result) {\n"
	"                        return false;\n"
	"                    }\n"
	"                }\n"
	"            }\n"
	"        }\n"
	"        return true;\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 写入数据\n"
	"     * @access public\n"
	"     * @param array      $data  数据数组\n"
	"     * @param array|true $field 允许字段\n"
	"     * @return $this\n"
	"     */\n"
	"    public static function create($data = [], $field = null)\n"
	"    {\n"
	"        $model = new static();\n"
	"        if (!empty($field)) {\n"
	"            $model->allowField($field);\n"
	"        }\n"
	"        $model->isUpdate(false)->save($data, []);\n"
	"        return $model;\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 更新数据\n"
	"     * @access public\n"
	"     * @param array      $data  数据数组\n"
	"     * @param array      $where 更新条件\n"
	"     * @param array|true $field 允许字段\n"
	"     * @return $this\n"
	"     */\n"
	"    public static function update($data = [], $where = [], $field = null)\n"
	"    {\n"
	"        $model = new static();\n"
	"        if (!empty($field)) {\n"
	"            $model->allowField($field);\n"
	"        }\n"
	"        $result = $model->isUpdate(true)->save($data, $where);\n"
	"        return $model;\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 查找单条记录\n"
	"     * @access public\n"
	"     * @param mixed        $data  主键值或者查询条件（闭包）\n"
	"     * @param array|string $with  关联预查询\n"
	"     * @param bool         $cache 是否缓存\n"
	"     * @return static|null\n"
	"     * @throws exception\\DbException\n"
	"     */\n"
	"    public static function get($data, $with = [], $cache = false)\n"
	"    {\n"
	"        if (is_null($data)) {\n"
	"            return;\n"
	"        }\n"
	"\n"
	"        if (true === $with || is_int($with)) {\n"
	"            $cache = $with;\n"
	"            $with  = [];\n"
	"        }\n"
	"        $query = static::parseQuery($data, $with, $cache);\n"
	"        return $query->find($data);\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 查找所有记录\n"
	"     * @access public\n"
	"     * @param mixed        $data  主键列表或者查询条件（闭包）\n"
	"     * @param array|string $with  关联预查询\n"
	"     * @param bool         $cache 是否缓存\n"
	"     * @return static[]|false\n"
	"     * @throws exception\\DbException\n"
	"     */\n"
	"    public static function all($data = null, $with = [], $cache = false)\n"
	"    {\n"
	"        if (true === $with || is_int($with)) {\n"
	"            $cache = $with;\n"
	"            $with  = [];\n"
	"        }\n"
	"        $query = static::parseQuery($data, $with, $cache);\n"
	"        return $query->select($data);\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 分析查询表达式\n"
	"     * @access public\n"
	"     * @param mixed  $data  主键列表或者查询条件（闭包）\n"
	"     * @param string $with  关联预查询\n"
	"     * @param bool   $cache 是否缓存\n"
	"     * @return Query\n"
	"     */\n"
	"    protected static function parseQuery(&$data, $with, $cache)\n"
	"    {\n"
	"        $result = self::with($with)->cache($cache);\n"
	"        if (is_array($data) && key($data) !== 0) {\n"
	"            $result = $result->where($data);\n"
	"            $data   = null;\n"
	"        } elseif ($data instanceof \\Closure) {\n"
	"            call_user_func_array($data, [ & $result]);\n"
	"            $data = null;\n"
	"        } elseif ($data instanceof Query) {\n"
	"            $result = $data->with($with)->cache($cache);\n"
	"            $data   = null;\n"
	"        }\n"
	"        return $result;\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 删除记录\n"
	"     * @access public\n"
	"     * @param mixed $data 主键列表 支持闭包查询条件\n"
	"     * @return integer 成功删除的记录数\n"
	"     */\n"
	"    public static function destroy($data)\n"
	"    {\n"
	"        $model = new static();\n"
	"        $query = $model->db();\n"
	"        if (empty($data) && 0 !== $data) {\n"
	"            return 0;\n"
	"        } elseif (is_array($data) && key($data) !== 0) {\n"
	"            $query->where($data);\n"
	"            $data = null;\n"
	"        } elseif ($data instanceof \\Closure) {\n"
	"            call_user_func_array($data, [ & $query]);\n"
	"            $data = null;\n"
	"        }\n"
	"        $resultSet = $query->select($data);\n"
	"        $count     = 0;\n"
	"        if ($resultSet) {\n"
	"            foreach ($resultSet as $data) {\n"
	"                $result = $data->delete();\n"
	"                $count += $result;\n"
	"            }\n"
	"        }\n"
	"        return $count;\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 命名范围\n"
	"     * @access public\n"
	"     * @param string|array|\\Closure $name 命名范围名称 逗号分隔\n"
	"     * @internal  mixed                 ...$params 参数调用\n"
	"     * @return Query\n"
	"     */\n"
	"    public static function scope($name)\n"
	"    {\n"
	"        $model  = new static();\n"
	"        $query  = $model->db();\n"
	"        $params = func_get_args();\n"
	"        array_shift($params);\n"
	"        array_unshift($params, $query);\n"
	"        if ($name instanceof \\Closure) {\n"
	"            call_user_func_array($name, $params);\n"
	"        } elseif (is_string($name)) {\n"
	"            $name = explode(\',\', $name);\n"
	"        }\n"
	"        if (is_array($name)) {\n"
	"            foreach ($name as $scope) {\n"
	"                $method = \'scope\' . trim($scope);\n"
	"                if (method_exists($model, $method)) {\n"
	"                    call_user_func_array([$model, $method], $params);\n"
	"                }\n"
	"            }\n"
	"        }\n"
	"        return $query;\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 设置是否使用全局查询范围\n"
	"     * @param bool $use 是否启用全局查询范围\n"
	"     * @access public\n"
	"     * @return Query\n"
	"     */\n"
	"    public static function useGlobalScope($use)\n"
	"    {\n"
	"        $model = new static();\n"
	"        return $model->db($use);\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 根据关联条件查询当前模型\n"
	"     * @access public\n"
	"     * @param string  $relation 关联方法名\n"
	"     * @param mixed   $operator 比较操作符\n"
	"     * @param integer $count    个数\n"
	"     * @param string  $id       关联表的统计字段\n"
	"     * @return Relation|Query\n"
	"     */\n"
	"    public static function has($relation, $operator = \'>=\', $count = 1, $id = \'*\')\n"
	"    {\n"
	"        $relation = (new static())->$relation();\n"
	"        if (is_array($operator) || $operator instanceof \\Closure) {\n"
	"            return $relation->hasWhere($operator);\n"
	"        }\n"
	"        return $relation->has($operator, $count, $id);\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 根据关联条件查询当前模型\n"
	"     * @access public\n"
	"     * @param  string $relation 关联方法名\n"
	"     * @param  mixed  $where    查询条件（数组或者闭包）\n"
	"     * @param  mixed  $fields   字段\n"
	"     * @return Relation|Query\n"
	"     */\n"
	"    public static function hasWhere($relation, $where = [], $fields = null)\n"
	"    {\n"
	"        return (new static())->$relation()->hasWhere($where, $fields);\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 解析模型的完整命名空间\n"
	"     * @access public\n"
	"     * @param string $model 模型名（或者完整类名）\n"
	"     * @return string\n"
	"     */\n"
	"    protected function parseModel($model)\n"
	"    {\n"
	"        if (false === strpos($model, \'\\\\\')) {\n"
	"            $path = explode(\'\\\\\', get_called_class());\n"
	"            array_pop($path);\n"
	"            array_push($path, Loader::parseName($model, 1));\n"
	"            $model = implode(\'\\\\\', $path);\n"
	"        }\n"
	"        return $model;\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 查询当前模型的关联数据\n"
	"     * @access public\n"
	"     * @param string|array $relations 关联名\n"
	"     * @return $this\n"
	"     */\n"
	"    public function relationQuery($relations)\n"
	"    {\n"
	"        if (is_string($relations)) {\n"
	"            $relations = explode(\',\', $relations);\n"
	"        }\n"
	"\n"
	"        foreach ($relations as $key => $relation) {\n"
	"            $subRelation = \'\';\n"
	"            $closure     = null;\n"
	"            if ($relation instanceof \\Closure) {\n"
	"                // 支持闭包查询过滤关联条件\n"
	"                $closure  = $relation;\n"
	"                $relation = $key;\n"
	"            }\n"
	"            if (is_array($relation)) {\n"
	"                $subRelation = $relation;\n"
	"                $relation    = $key;\n"
	"            } elseif (strpos($relation, \'.\')) {\n"
	"                list($relation, $subRelation) = explode(\'.\', $relation, 2);\n"
	"            }\n"
	"            $method                = Loader::parseName($relation, 1, false);\n"
	"            $this->data[$relation] = $this->$method()->getRelation($subRelation, $closure);\n"
	"        }\n"
	"        return $this;\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 预载入关联查询 返回数据集\n"
	"     * @access public\n"
	"     * @param array  $resultSet 数据集\n"
	"     * @param string $relation  关联名\n"
	"     * @return array\n"
	"     */\n"
	"    public function eagerlyResultSet(&$resultSet, $relation)\n"
	"    {\n"
	"        $relations = is_string($relation) ? explode(\',\', $relation) : $relation;\n"
	"        foreach ($relations as $key => $relation) {\n"
	"            $subRelation = \'\';\n"
	"            $closure     = false;\n"
	"            if ($relation instanceof \\Closure) {\n"
	"                $closure  = $relation;\n"
	"                $relation = $key;\n"
	"            }\n"
	"            if (is_array($relation)) {\n"
	"                $subRelation = $relation;\n"
	"                $relation    = $key;\n"
	"            } elseif (strpos($relation, \'.\')) {\n"
	"                list($relation, $subRelation) = explode(\'.\', $relation, 2);\n"
	"            }\n"
	"            $relation = Loader::parseName($relation, 1, false);\n"
	"            $this->$relation()->eagerlyResultSet($resultSet, $relation, $subRelation, $closure);\n"
	"        }\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 预载入关联查询 返回模型对象\n"
	"     * @access public\n"
	"     * @param Model  $result   数据对象\n"
	"     * @param string $relation 关联名\n"
	"     * @return Model\n"
	"     */\n"
	"    public function eagerlyResult(&$result, $relation)\n"
	"    {\n"
	"        $relations = is_string($relation) ? explode(\',\', $relation) : $relation;\n"
	"\n"
	"        foreach ($relations as $key => $relation) {\n"
	"            $subRelation = \'\';\n"
	"            $closure     = false;\n"
	"            if ($relation instanceof \\Closure) {\n"
	"                $closure  = $relation;\n"
	"                $relation = $key;\n"
	"            }\n"
	"            if (is_array($relation)) {\n"
	"                $subRelation = $relation;\n"
	"                $relation    = $key;\n"
	"            } elseif (strpos($relation, \'.\')) {\n"
	"                list($relation, $subRelation) = explode(\'.\', $relation, 2);\n"
	"            }\n"
	"            $relation = Loader::parseName($relation, 1, false);\n"
	"            $this->$relation()->eagerlyResult($result, $relation, $subRelation, $closure);\n"
	"        }\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 关联统计\n"
	"     * @access public\n"
	"     * @param Model        $result   数据对象\n"
	"     * @param string|array $relation 关联名\n"
	"     * @return void\n"
	"     */\n"
	"    public function relationCount(&$result, $relation)\n"
	"    {\n"
	"        $relations = is_string($relation) ? explode(\',\', $relation) : $relation;\n"
	"\n"
	"        foreach ($relations as $key => $relation) {\n"
	"            $closure = false;\n"
	"            if ($relation instanceof \\Closure) {\n"
	"                $closure  = $relation;\n"
	"                $relation = $key;\n"
	"            } elseif (is_string($key)) {\n"
	"                $name     = $relation;\n"
	"                $relation = $key;\n"
	"            }\n"
	"            $relation = Loader::parseName($relation, 1, false);\n"
	"            $count    = $this->$relation()->relationCount($result, $closure);\n"
	"            if (!isset($name)) {\n"
	"                $name = Loader::parseName($relation) . \'_count\';\n"
	"            }\n"
	"            $result->setAttr($name, $count);\n"
	"        }\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 获取模型的默认外键名\n"
	"     * @access public\n"
	"     * @param string $name 模型名\n"
	"     * @return string\n"
	"     */\n"
	"    protected function getForeignKey($name)\n"
	"    {\n"
	"        if (strpos($name, \'\\\\\')) {\n"
	"            $name = basename(str_replace(\'\\\\\', \'/\', $name));\n"
	"        }\n"
	"        return Loader::parseName($name) . \'_id\';\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * HAS ONE 关联定义\n"
	"     * @access public\n"
	"     * @param string $model      模型名\n"
	"     * @param string $foreignKey 关联外键\n"
	"     * @param string $localKey   当前模型主键\n"
	"     * @param array  $alias      别名定义（已经废弃）\n"
	"     * @param string $joinType   JOIN类型\n"
	"     * @return HasOne\n"
	"     */\n"
	"    public function hasOne($model, $foreignKey = \'\', $localKey = \'\', $alias = [], $joinType = \'INNER\')\n"
	"    {\n"
	"        // 记录当前关联信息\n"
	"        $model      = $this->parseModel($model);\n"
	"        $localKey   = $localKey ?: $this->getPk();\n"
	"        $foreignKey = $foreignKey ?: $this->getForeignKey($this->name);\n"
	"        return new HasOne($this, $model, $foreignKey, $localKey, $joinType);\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * BELONGS TO 关联定义\n"
	"     * @access public\n"
	"     * @param string $model      模型名\n"
	"     * @param string $foreignKey 关联外键\n"
	"     * @param string $localKey   关联主键\n"
	"     * @param array  $alias      别名定义（已经废弃）\n"
	"     * @param string $joinType   JOIN类型\n"
	"     * @return BelongsTo\n"
	"     */\n"
	"    public function belongsTo($model, $foreignKey = \'\', $localKey = \'\', $alias = [], $joinType = \'INNER\')\n"
	"    {\n"
	"        // 记录当前关联信息\n"
	"        $model      = $this->parseModel($model);\n"
	"        $foreignKey = $foreignKey ?: $this->getForeignKey($model);\n"
	"        $localKey   = $localKey ?: (new $model)->getPk();\n"
	"        $trace      = debug_backtrace(false, 2);\n"
	"        $relation   = Loader::parseName($trace[1][\'function\']);\n"
	"        return new BelongsTo($this, $model, $foreignKey, $localKey, $joinType, $relation);\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * HAS MANY 关联定义\n"
	"     * @access public\n"
	"     * @param string $model      模型名\n"
	"     * @param string $foreignKey 关联外键\n"
	"     * @param string $localKey   当前模型主键\n"
	"     * @return HasMany\n"
	"     */\n"
	"    public function hasMany($model, $foreignKey = \'\', $localKey = \'\')\n"
	"    {\n"
	"        // 记录当前关联信息\n"
	"        $model      = $this->parseModel($model);\n"
	"        $localKey   = $localKey ?: $this->getPk();\n"
	"        $foreignKey = $foreignKey ?: $this->getForeignKey($this->name);\n"
	"        return new HasMany($this, $model, $foreignKey, $localKey);\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * HAS MANY 远程关联定义\n"
	"     * @access public\n"
	"     * @param string $model      模型名\n"
	"     * @param string $through    中间模型名\n"
	"     * @param string $foreignKey 关联外键\n"
	"     * @param string $throughKey 关联外键\n"
	"     * @param string $localKey   当前模型主键\n"
	"     * @return HasManyThrough\n"
	"     */\n"
	"    public function hasManyThrough($model, $through, $foreignKey = \'\', $throughKey = \'\', $localKey = \'\')\n"
	"    {\n"
	"        // 记录当前关联信息\n"
	"        $model      = $this->parseModel($model);\n"
	"        $through    = $this->parseModel($through);\n"
	"        $localKey   = $localKey ?: $this->getPk();\n"
	"        $foreignKey = $foreignKey ?: $this->getForeignKey($this->name);\n"
	"        $throughKey = $throughKey ?: $this->getForeignKey($through);\n"
	"        return new HasManyThrough($this, $model, $through, $foreignKey, $throughKey, $localKey);\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * BELONGS TO MANY 关联定义\n"
	"     * @access public\n"
	"     * @param string $model      模型名\n"
	"     * @param string $table      中间表名\n"
	"     * @param string $foreignKey 关联外键\n"
	"     * @param string $localKey   当前模型关联键\n"
	"     * @return BelongsToMany\n"
	"     */\n"
	"    public function belongsToMany($model, $table = \'\', $foreignKey = \'\', $localKey = \'\')\n"
	"    {\n"
	"        // 记录当前关联信息\n"
	"        $model      = $this->parseModel($model);\n"
	"        $name       = Loader::parseName(basename(str_replace(\'\\\\\', \'/\', $model)));\n"
	"        $table      = $table ?: Loader::parseName($this->name) . \'_\' . $name;\n"
	"        $foreignKey = $foreignKey ?: $name . \'_id\';\n"
	"        $localKey   = $localKey ?: $this->getForeignKey($this->name);\n"
	"        return new BelongsToMany($this, $model, $table, $foreignKey, $localKey);\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * MORPH  MANY 关联定义\n"
	"     * @access public\n"
	"     * @param string       $model 模型名\n"
	"     * @param string|array $morph 多态字段信息\n"
	"     * @param string       $type  多态类型\n"
	"     * @return MorphMany\n"
	"     */\n"
	"    public function morphMany($model, $morph = null, $type = \'\')\n"
	"    {\n"
	"        // 记录当前关联信息\n"
	"        $model = $this->parseModel($model);\n"
	"        if (is_null($morph)) {\n"
	"            $trace = debug_backtrace(false, 2);\n"
	"            $morph = Loader::parseName($trace[1][\'function\']);\n"
	"        }\n"
	"        $type = $type ?: get_class($this);\n"
	"        if (is_array($morph)) {\n"
	"            list($morphType, $foreignKey) = $morph;\n"
	"        } else {\n"
	"            $morphType  = $morph . \'_type\';\n"
	"            $foreignKey = $morph . \'_id\';\n"
	"        }\n"
	"        return new MorphMany($this, $model, $foreignKey, $morphType, $type);\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * MORPH  One 关联定义\n"
	"     * @access public\n"
	"     * @param string       $model 模型名\n"
	"     * @param string|array $morph 多态字段信息\n"
	"     * @param string       $type  多态类型\n"
	"     * @return MorphOne\n"
	"     */\n"
	"    public function morphOne($model, $morph = null, $type = \'\')\n"
	"    {\n"
	"        // 记录当前关联信息\n"
	"        $model = $this->parseModel($model);\n"
	"        if (is_null($morph)) {\n"
	"            $trace = debug_backtrace(false, 2);\n"
	"            $morph = Loader::parseName($trace[1][\'function\']);\n"
	"        }\n"
	"        $type = $type ?: get_class($this);\n"
	"        if (is_array($morph)) {\n"
	"            list($morphType, $foreignKey) = $morph;\n"
	"        } else {\n"
	"            $morphType  = $morph . \'_type\';\n"
	"            $foreignKey = $morph . \'_id\';\n"
	"        }\n"
	"        return new MorphOne($this, $model, $foreignKey, $morphType, $type);\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * MORPH TO 关联定义\n"
	"     * @access public\n"
	"     * @param string|array $morph 多态字段信息\n"
	"     * @param array        $alias 多态别名定义\n"
	"     * @return MorphTo\n"
	"     */\n"
	"    public function morphTo($morph = null, $alias = [])\n"
	"    {\n"
	"        $trace    = debug_backtrace(false, 2);\n"
	"        $relation = Loader::parseName($trace[1][\'function\']);\n"
	"\n"
	"        if (is_null($morph)) {\n"
	"            $morph = $relation;\n"
	"        }\n"
	"        // 记录当前关联信息\n"
	"        if (is_array($morph)) {\n"
	"            list($morphType, $foreignKey) = $morph;\n"
	"        } else {\n"
	"            $morphType  = $morph . \'_type\';\n"
	"            $foreignKey = $morph . \'_id\';\n"
	"        }\n"
	"        return new MorphTo($this, $morphType, $foreignKey, $alias, $relation);\n"
	"    }\n"
	"\n"
	"    public function __call($method, $args)\n"
	"    {\n"
	"        $query = $this->db(true, false);\n"
	"        if (method_exists($this, \'scope\' . $method)) {\n"
	"            // 动态调用命名范围\n"
	"            $method = \'scope\' . $method;\n"
	"            array_unshift($args, $query);\n"
	"            call_user_func_array([$this, $method], $args);\n"
	"            return $this;\n"
	"        } else {\n"
	"            return call_user_func_array([$query, $method], $args);\n"
	"        }\n"
	"    }\n"
	"\n"
	"    public static function __callStatic($method, $args)\n"
	"    {\n"
	"        $model = new static();\n"
	"        $query = $model->db();\n"
	"        if (method_exists($model, \'scope\' . $method)) {\n"
	"            // 动态调用命名范围\n"
	"            $method = \'scope\' . $method;\n"
	"            array_unshift($args, $query);\n"
	"\n"
	"            call_user_func_array([$model, $method], $args);\n"
	"            return $query;\n"
	"        } else {\n"
	"            return call_user_func_array([$query, $method], $args);\n"
	"        }\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 修改器 设置数据对象的值\n"
	"     * @access public\n"
	"     * @param string $name  名称\n"
	"     * @param mixed  $value 值\n"
	"     * @return void\n"
	"     */\n"
	"    public function __set($name, $value)\n"
	"    {\n"
	"        $this->setAttr($name, $value);\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 获取器 获取数据对象的值\n"
	"     * @access public\n"
	"     * @param string $name 名称\n"
	"     * @return mixed\n"
	"     */\n"
	"    public function __get($name)\n"
	"    {\n"
	"        return $this->getAttr($name);\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 检测数据对象的值\n"
	"     * @access public\n"
	"     * @param string $name 名称\n"
	"     * @return boolean\n"
	"     */\n"
	"    public function __isset($name)\n"
	"    {\n"
	"        try {\n"
	"            if (array_key_exists($name, $this->data) || array_key_exists($name, $this->relation)) {\n"
	"                return true;\n"
	"            } else {\n"
	"                $this->getAttr($name);\n"
	"                return true;\n"
	"            }\n"
	"        } catch (InvalidArgumentException $e) {\n"
	"            return false;\n"
	"        }\n"
	"\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 销毁数据对象的值\n"
	"     * @access public\n"
	"     * @param string $name 名称\n"
	"     * @return void\n"
	"     */\n"
	"    public function __unset($name)\n"
	"    {\n"
	"        unset($this->data[$name], $this->relation[$name]);\n"
	"    }\n"
	"\n"
	"    public function __toString()\n"
	"    {\n"
	"        return $this->toJson();\n"
	"    }\n"
	"\n"
	"    // JsonSerializable\n"
	"    public function jsonSerialize()\n"
	"    {\n"
	"        return $this->toArray();\n"
	"    }\n"
	"\n"
	"    // ArrayAccess\n"
	"    public function offsetSet($name, $value)\n"
	"    {\n"
	"        $this->setAttr($name, $value);\n"
	"    }\n"
	"\n"
	"    public function offsetExists($name)\n"
	"    {\n"
	"        return $this->__isset($name);\n"
	"    }\n"
	"\n"
	"    public function offsetUnset($name)\n"
	"    {\n"
	"        $this->__unset($name);\n"
	"    }\n"
	"\n"
	"    public function offsetGet($name)\n"
	"    {\n"
	"        return $this->getAttr($name);\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 解序列化后处理\n"
	"     */\n"
	"    public function __wakeup()\n"
	"    {\n"
	"        $this->initialize();\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 模型事件快捷方法\n"
	"     * @param      $callback\n"
	"     * @param bool $override\n"
	"     */\n"
	"    protected static function beforeInsert($callback, $override = false)\n"
	"    {\n"
	"        self::event(\'before_insert\', $callback, $override);\n"
	"    }\n"
	"\n"
	"    protected static function afterInsert($callback, $override = false)\n"
	"    {\n"
	"        self::event(\'after_insert\', $callback, $override);\n"
	"    }\n"
	"\n"
	"    protected static function beforeUpdate($callback, $override = false)\n"
	"    {\n"
	"        self::event(\'before_update\', $callback, $override);\n"
	"    }\n"
	"\n"
	"    protected static function afterUpdate($callback, $override = false)\n"
	"    {\n"
	"        self::event(\'after_update\', $callback, $override);\n"
	"    }\n"
	"\n"
	"    protected static function beforeWrite($callback, $override = false)\n"
	"    {\n"
	"        self::event(\'before_write\', $callback, $override);\n"
	"    }\n"
	"\n"
	"    protected static function afterWrite($callback, $override = false)\n"
	"    {\n"
	"        self::event(\'after_write\', $callback, $override);\n"
	"    }\n"
	"\n"
	"    protected static function beforeDelete($callback, $override = false)\n"
	"    {\n"
	"        self::event(\'before_delete\', $callback, $override);\n"
	"    }\n"
	"\n"
	"    protected static function afterDelete($callback, $override = false)\n"
	"    {\n"
	"        self::event(\'after_delete\', $callback, $override);\n"
	"    }\n"
	"\n"
	"}\n"
	"\n"
;
#endif